<?php
namespace restphp\driver;

use restphp\utils\RestReflection;
use restphp\utils\RestStringUtils;
use restphp\validate\RestValidate;

/**
 * Class RestRepositoryHelper
 * @package restphp\driver
 */
final class RestRepositoryHelper {
    /**
     * 获取主键字段。
     * @param $classInstance
     * @return array
     * @throws \ReflectionException
     */
    public static function getPrimaryRule($classInstance) {
        $reflection = new \ReflectionClass($classInstance);
        $properties = $reflection->getProperties();
        $arrCheck = array();
        foreach ($properties as $propItem) {
            $name = $propItem->getName();
            $getterName = RestReflection::getGetterName($name);
            if (!$reflection->hasMethod($getterName)) {
                continue;
            }
            $val = $classInstance->$getterName();
            $doc = $propItem->getDocComment();

            $arrDoc = RestReflection::clearDocToArr($doc);
            foreach ($arrDoc as $item) {
                if (RestStringUtils::startWith($item, '@primary') && !RestStringUtils::isBlank($val)) {
                    return array(self::getPropColumn($name) => $val);
                }
            }
        }
        return $arrCheck;
    }

    /**
     * 获取主键列名.
     * @param $classInstance
     * @param string $strDef
     * @return false|string
     * @throws \ReflectionException
     */
    public static function getPrimaryKeyName($classInstance, $strDef = 'id') {
        $reflection = new \ReflectionClass($classInstance);
        $properties = $reflection->getProperties();
        foreach ($properties as $propItem) {
            $name = $propItem->getName();
            $getterName = RestReflection::getGetterName($name);
            if (!$reflection->hasMethod($getterName)) {
                continue;
            }
            $doc = $propItem->getDocComment();

            $arrDoc = RestReflection::clearDocToArr($doc);
            foreach ($arrDoc as $item) {
                if (RestStringUtils::startWith($item, '@primary')) {
                    return self::getPropColumn($name);
                }
            }
        }
        return $strDef;
    }

    /**
     * 获取property对应数据库字段名.
     * @param $propName
     * @return false|string
     */
    public static function getPropColumn($propName) {
        $firstChar = substr($propName, 0, 1);
        if ('_' == $firstChar) {
            $propName = substr($propName, 1);
            return self::getPropColumn($propName);
        }
        return $propName;
    }

    public static function autoFillValue(&$classInstance) {
        $reflection = new \ReflectionClass($classInstance);
        $properties = $reflection->getProperties();
        foreach ($properties as $propItem) {
            $name = $propItem->getName();
            $setterName = RestReflection::getSetterName($name);
            if (!$reflection->hasMethod($setterName)) {
                continue;
            }
            $doc = $propItem->getDocComment();

            $arrDoc = RestReflection::clearDocToArr($doc);
            foreach ($arrDoc as $item) {
                if (RestStringUtils::startWith($item, '@autoValue')) {
                    if (strpos($item, '(') > -1) {
                        $paramContent = RestValidate::getRuleStr($item);
                        $arrParams = explode(',', $paramContent);
                        $createMethod = '';
                        $arrArgs = array();
                        foreach ($arrParams as $content) {
                            if (preg_match('/value\\s*=\\s*/', $content)) {
                                $createMethod = preg_replace('/value\\s*=\\s*/', '', $content);
                                $createMethod = trim($createMethod);
                                $createMethod = RestValidate::clearMessageBoundary($createMethod);
                            } else {
                                if (strpos($content, '=') > -1) {
                                    $arrParameter = explode('=', $content);
                                    $arrArgs[trim($arrParameter[0])] = RestValidate::clearMessageBoundary(trim($arrParameter[1]));
                                } else {
                                    $arrArgs[] = $content;
                                }
                            }
                        }
                        if (!RestStringUtils::isBlank($createMethod)) {
                            if ('uuid' == $createMethod) {
                                $classInstance->$setterName(\restphp\utils\RestUUIDUtil::guid());
                            } else if ('now' == $createMethod) {
                                $classInstance->$setterName(date('Y-m-d H:i:s'));
                            } else {
                                $classInstance->$setterName(call_user_func($createMethod, $arrArgs));
                            }
                        }
                    }
                }
            }
        }
        return $classInstance;
    }
}